package com.tushare.util;

import com.tushare.network.WapResponse;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public class TransformClassUtil {

    public <T> List<T> initList(WapResponse.WapData data, Class<T> inputClass) {
        List<String> fields = data.getFields();
        List<List<Object>> dataList = data.getItems();
        if (data.getFields() == null
                || data.getFields().size() == 0 || data.getItems() == null) {
            return null;
        }
        try {
            Constructor<T> constructor = inputClass.getConstructor();
            List<T> list = new ArrayList<>();
            for (List<Object> entity : dataList) {
                T instance = constructor.newInstance();
                initInstance(instance, inputClass, fields, entity);
                list.add(instance);
            }
            return list;
        } catch (NoSuchMethodException | InstantiationException
                 | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
            return null;
        }
    }

    private <T> void initInstance(T instance, Class<T> inputClass, List<String> fields, List<Object> dataList)
            throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        int index;
        String attributeName;
        Object fieldValue;
        Field[] declaredFields = inputClass.getDeclaredFields();
        for (Field field : declaredFields) {
            attributeName = field.getName();
            index = fields.indexOf(attributeName);
            if (index < 0) {
                continue;
            }
            field.setAccessible(true);
            attributeName = attributeName.substring(0, 1).toUpperCase() + attributeName.substring(1);
            Method method = inputClass.getDeclaredMethod("set" + attributeName, field.getType());
            fieldValue = dataList.get(index);
            if (field.getType() == float.class) {
                if (fieldValue == null) {
                    method.invoke(instance, 0.0f);
                } else if (fieldValue instanceof Double) {
                    method.invoke(instance, ((Double) fieldValue).floatValue());
                } else {
                    method.invoke(instance, fieldValue);
                }
            } else if (field.getType() == int.class) {
                if (fieldValue == null) {
                    method.invoke(instance, 0);
                } else if (fieldValue instanceof String) {
                    method.invoke(instance, Integer.parseInt((String) fieldValue));
                } else {
                    method.invoke(instance, fieldValue);
                }
            } else {
                method.invoke(instance, fieldValue);
            }
        }
    }

}
